/*
 * Copyright (C) 2016 mzlion(and.mz.yq@gmail.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mzlion.easyokhttp.request.param;

import com.mzlion.core.io.IOUtils;
import com.mzlion.core.lang.Assert;
import okhttp3.MediaType;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;

/**
 * <p>
 * 带有文件上传
 * </p>
 *
 * @author mzlion on 2016/5/15.
 */
public class UploadFileWrapper {

    private byte[] content;

    private File file;

    private long contentLength;

    private MediaType mediaType;

    private String filename;

    private UploadFileWrapper(Builder builder) {
        this.file = builder.file;
        this.content = builder.content;
        this.contentLength = builder.contentLength;
        this.mediaType = builder.mediaType;
        this.filename = builder.filename;
    }

    public byte[] getContent() {
        return content;
    }

    public File getFile() {
        return file;
    }

    public long getContentLength() {
        return contentLength;
    }

    public MediaType getMediaType() {
        return mediaType;
    }

    public String getFilename() {
        return filename;
    }

    public static final class Builder {

        private byte[] content;
        private File file;
        private long contentLength;
        private String filename;
        private MediaType mediaType;

        public Builder file(File file) {
            Assert.notNull(file, "File must not be null.");
            if (!file.exists()) {
                throw new IllegalArgumentException("File does not exist.");
            }
            this.file = file;
            this.contentLength = file.length();
            this.filename = file.getName();
            return this;
        }

        public Builder filename(String filename) {
            Assert.hasLength(filename, "Filename must not be null.");
            this.filename = filename;
            return this;
        }

        public Builder stream(InputStream stream) {
            Assert.notNull(stream, "Stream must not be null.");
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            this.contentLength = IOUtils.copy(stream, outputStream);
            this.content = outputStream.toByteArray();
            return this;
        }

        public Builder contentType(String contentType) {
            Assert.hasLength(contentType, "ContentType must not be null.");
            this.mediaType = MediaType.parse(contentType);
            return this;
        }

        public Builder mediaType(MediaType mediaType) {
            this.mediaType = mediaType;
            return this;
        }

        public UploadFileWrapper build() {
            if (content == null && this.file == null) {
                throw new IllegalStateException("The Content or file is null.");
            }
            if (this.filename == null) {
                throw new NullPointerException("Filename must not be null.");
            }
            return new UploadFileWrapper(this);
        }
    }
}
